/*
R.init
RipplePersistance.pack


*/
RipplePersistance{	
	
	*pack{|path|
		var xb, doc, f;
		
		if(path.find(".rpl") != (path.size - 4)){
			path = path ++ ".rpl"
		};
		
		doc = DOMDocument.new;
		xb = XMLNodeBuilder.new;
		xb.setDocument(doc);
		Ripple.accept(xb);
		f = File(path, "w");
		~tree = doc;
		doc.write(f);
		f.close;
	}
	
	*unPack{|path|
		var voices, name, audioFile, d, connections, pages, loadedVoices;
		
		loadedVoices = List.new;
		
		d = DOMDocument.new(path);
		
		pages = d.getDocumentElement.getElementsByTagName("page");
		
		if(pages.size == 0){ // backwards compatibility. If not pages, treat root as page
			pages = d.getDocumentElement.getElementsByTagName("ripple");
		};
		
		~pages = pages;
		
		pages.do({|pageNode, index|
			
			Ripple.setVoicePage(index);
			
			voices = pageNode.getElementsByTagName("voice");
			
			voices.do{|voiceNode|
				var voices, name, audioFile, controls, synthType, voice;
				name = voiceNode.getElement("name").getText;
				voice = Ripple.launchSLFromPath(
						voiceNode.getElement("synthType").getText.interpret,
						DOMDocument.decodeStandardEntities( voiceNode.getElement("audioFile").getText ),
						name;
					);
				voice.setMidiChannel( voiceNode.getElement("midiChannel").getText );
				voice.setPoly( voiceNode.getElement("polyPhonic").getText == "true" );
				
				controls = voiceNode.getElementsByTagName("control");
				controls.do{|control|
					var controlName = control.getElement("name").getText.asSymbol;
					voice.setControlValue(controlName, control.getElement("value").getText.asFloat);
					if(control.getElement("rand") != nil){
						voice.setControlValue(controlName, control.getElement("rand").getText.asFloat, \Rand);
					};
					control.getElementsByTagName("plugin").do{|pluginNode|
						var plugin;
						plugin = pluginNode.getElement("pluginClass").getText.interpret.new;
						pluginNode.getElementsByTagName("setting").do{|settingNode|
							plugin.setValue(
								settingNode.getAttribute("name").asSymbol,
								settingNode.getAttribute("value")
							);	
						};
						voice.addPlugin(controlName, plugin);	
					}
				};
				
				loadedVoices.add(voice);
			};

		
		
		});
		
		Ripple.setVoicePage(0);
		
		connections =  d.getDocumentElement.getElementsByTagName("connection");
		connections.do{|conn|
			Ripple.addConnection(
				conn.getElement("sourceName").getText,
				conn.getElement("targetName").getText,
				conn.getElement("connectionClass").getText
			);
		
		};
		
		^loadedVoices;
		
	}	
	
	
}










